package com.liqi.web.service.dev;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liqi.common.core.domain.R;
import com.liqi.common.utils.SecurityUtils;
import com.liqi.common.utils.uuid.GenerateCodeUtils;
import com.liqi.dev.domain.CfgBranch;
import com.liqi.dev.domain.CfgSubject;
import com.liqi.dev.domain.RelServiceBranch;
import com.liqi.dev.domain.RelServiceSubject;
import com.liqi.dev.mapper.CfgBranchMapper;
import com.liqi.dev.mapper.CfgSubjectMapper;
import com.liqi.dev.mapper.RelServiceBranchMapper;
import com.liqi.dev.mapper.RelServiceSubjectMapper;
import com.liqi.dev.pojo.CfgBranchDTO;
import com.liqi.dev.pojo.CfgBranchVO;
import com.liqi.items.mapper.TCfgSubjectMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 网点表 服务实现类
 * </p>
 *
 * @author tianye
 * @since 2022-04-14
 */
@Service
public class CfgBranchService extends ServiceImpl<CfgBranchMapper, CfgBranch> {

    @Autowired
    private RelServiceBranchMapper relServiceBranchMapper;

    @Autowired
    private CfgSubjectMapper cfgSubjectMapper;

    @Autowired
    private RelServiceSubjectMapper relServiceSubjectMapper;

    @Autowired
    private CfgBranchMapper cfgBranchMapper;
    
    @Autowired
    private TCfgSubjectMapper tCfgSubjectMapper;
    // 复制网点
    @Transactional
    public R copy(CfgBranchDTO cfgBranchDTO) {

        // 0.判断
        Assert.isTrue(!cfgBranchDTO.getSourceBranchCode().equals(cfgBranchDTO.getTargetBranchCode()), "源网点编码和目标编码不能相同！");

        // 1.目标事项
        List<String> targetServiceCode = this.listServiceCode(cfgBranchDTO.getTargetBranchCode());

        // 2.验证源网点主题
        this.listSubject(cfgBranchDTO.getSourceBranchCode(),cfgBranchDTO.getSourceSystemType());

        // 3.删除目标网点的关联事项
        this.delete(cfgBranchDTO.getTargetBranchCode(),cfgBranchDTO.getTargetSystemType());

        // 4.源主题(树形结构)
        CfgSubject sourceSubject = new CfgSubject();
        this.sourceSubject(sourceSubject, cfgBranchDTO.getSourceBranchCode(),cfgBranchDTO.getSourceSystemType(), "0", targetServiceCode);

        // 5.复制数据
        this.copy(cfgBranchDTO.getTargetBranchCode(), sourceSubject.getChildList(), "0",cfgBranchDTO.getTargetSystemType());

        return R.ok();
    }

    // 源主题
    private void sourceSubject(CfgSubject sourceSubject, String sourceBranchCode,Integer systemType,
                               String parentSubjectCode, List<String> targetServiceCode) {
        // 获取子主题
        List<CfgSubject> cfgSubjects = this.childSubject(parentSubjectCode, sourceBranchCode,systemType);
        if (!CollectionUtils.isEmpty(cfgSubjects)) {

            // 赋值
            sourceSubject.setChildList(cfgSubjects);

            for (CfgSubject cfgSubject : cfgSubjects) {

                // 获取主题下面的事项
                List<RelServiceSubject> serviceList = this.listService(cfgSubject.getSubjectCode());
                if (!CollectionUtils.isEmpty(serviceList)) {
                    List<RelServiceSubject> readyList = new ArrayList<>();
                    for (RelServiceSubject service : serviceList) {
                        // 验证事项
                        if (targetServiceCode.contains(service.getServiceCode())) {
                            readyList.add(service);
                        }
                    }
                    cfgSubject.setServiceList(readyList);
                }

                this.sourceSubject(cfgSubject, sourceBranchCode,systemType, cfgSubject.getSubjectCode(), targetServiceCode);
            }
        }
    }

    // 删除目标网点关联的主题，事项
    private void delete(String targetBranchCode,Integer systemType) {
        // 删除主题事项
        relServiceSubjectMapper.deleteService(targetBranchCode,SecurityUtils.getUsername(), systemType);
        // 删除主题
        QueryWrapper<CfgSubject> qwSubject = new QueryWrapper<>();
        qwSubject.eq("branch_code", targetBranchCode);
        qwSubject.eq("system_type", systemType);
        qwSubject.eq("status", 0);
        CfgSubject subject = new CfgSubject();
        subject.setStatus(true);
        subject.setUpdateBy(SecurityUtils.getUsername());
        subject.setUpdateTime(new Date());
        cfgSubjectMapper.update(subject, qwSubject);
    }

    // 复制数据
    private void copy(String targetBranchCode, List<CfgSubject> sourceSubject, String parentSubjectCode,Integer stytemType) {
        // 判空
        if (CollectionUtils.isEmpty(sourceSubject)) {
            return;
        }

        for (CfgSubject k : sourceSubject) {
            // 主题
            k.setId(null);
            k.setSubjectCode(this.genSubjectCode());
            k.setParentSubjectCode(parentSubjectCode);
            if (parentSubjectCode.equals("0")) {
                k.setAncestors("0");
			}else {
	            k.setAncestors(tCfgSubjectMapper.selectAncestors(parentSubjectCode)+","+parentSubjectCode);
			}
            k.setBranchCode(targetBranchCode);
            k.setSystemType(stytemType);
            k.setCreateBy(SecurityUtils.getUsername());
            k.setCreateTime(new Date());
            k.setUpdateBy(SecurityUtils.getUsername());
            k.setUpdateTime(new Date());
            cfgSubjectMapper.insert(k);

            // 事项
            if (!CollectionUtils.isEmpty(k.getServiceList())) {
                for (RelServiceSubject service : k.getServiceList()) {
                    service.setId(null);
                    service.setSubjectCode(k.getSubjectCode());
                    service.setCreateBy(SecurityUtils.getUsername());
                    service.setCreateTime(new Date());
                    service.setUpdateBy(SecurityUtils.getUsername());
                    service.setUpdateTime(new Date());
                    relServiceSubjectMapper.insert(service);
                }
            }

            // 回调自己
            this.copy(targetBranchCode, k.getChildList(), k.getSubjectCode(),stytemType);
        }
    }

    // 网点下的主题
    private List<CfgSubject> listSubject(String branchCode,Integer systemType) {
        QueryWrapper<CfgSubject> qw = new QueryWrapper<>();
        qw.eq("branch_code", branchCode);
        qw.eq("system_type", systemType);
        qw.eq("status", 0);
        qw.orderByAsc("sort");
        List<CfgSubject> list = cfgSubjectMapper.selectList(qw);
        Assert.notEmpty(list, "源网点没有主题，禁止复制！");
        return list;
    }

    // 网点下面的事项
    private List<String> listServiceCode(String branchCode) {
        QueryWrapper<RelServiceBranch> qw = new QueryWrapper<>();
        qw.eq("branch_code", branchCode);
        qw.eq("status", 0);
        List<RelServiceBranch> list = relServiceBranchMapper.selectList(qw);
        //Assert.notEmpty(list, "目标网点没有事项，禁止复制！");
        return list.stream().map(e -> e.getServiceCode()).collect(Collectors.toList());
    }

    // 获取子主题
    private List<CfgSubject> childSubject(String parentSubjectCode, String branchCode,Integer systemType) {
        QueryWrapper<CfgSubject> qw = new QueryWrapper<>();
        qw.eq("parent_subject_code", parentSubjectCode);
        qw.eq("branch_code", branchCode);
        qw.eq("system_type", systemType);
        qw.eq("status", 0);
        qw.orderByAsc("sort");
        return cfgSubjectMapper.selectList(qw);
    }
    
    
    // 主题下面的事项
    private List<RelServiceSubject> listService(String subjectCode) {
        QueryWrapper<RelServiceSubject> qw = new QueryWrapper<>();
        qw.eq("subject_code", subjectCode);
        qw.eq("status", 0);
        qw.orderByAsc("sort");
        return relServiceSubjectMapper.selectList(qw);
    }

    // 生成主题编码
    private String genSubjectCode() {
        return GenerateCodeUtils.getSequnce();
    }

    // 办事网点树形列表
    public List<CfgBranchVO> branchTree() {
        // 获取顶级列表
        List<CfgBranchVO> topList = cfgBranchMapper.queryBranchByParentCode("0");
        // 获取树级列表
        return this.branchTree(topList);
    }

    // 获取树级列表
    private List<CfgBranchVO> branchTree(List<CfgBranchVO> cfgBranchList) {
        for (CfgBranchVO branch : cfgBranchList) {
            List<CfgBranchVO> cfgBranches = cfgBranchMapper.queryBranchByParentCode(branch.getBranchCode());
            if (!CollectionUtils.isEmpty(cfgBranches)) {
                branch.setChildren(cfgBranches);
                branchTree(cfgBranches);
            }
        }
        return cfgBranchList;
    }

}
